/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 - 2008 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/

package com.genia.toolbox.web.gwt.basics.client.widget;

import java.util.Date;

import com.genia.toolbox.web.gwt.basics.client.CssNames;
import com.genia.toolbox.web.gwt.basics.client.listener.CustomDelegatingChangeListenerCollection;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;

/**
 * GWT widget to choose a time.
 */
public class DateTimeChooser
    extends Composite
    implements AbstractDateChooser
{

  /**
   * number of ms in a day.
   */
  private static final long MS_BY_DAY = 1000l * 60 * 60 * 24;

  /**
   * the registered {@link ChangeListener}s.
   */
  private CustomDelegatingChangeListenerCollection changeListeners = new CustomDelegatingChangeListenerCollection(this);

  /**
   * {@link DateChooser} to choose the date.
   */
  private final DateChooser dateChooser = new DateChooser();

  /**
   * {@link TimeChooser} to choose the time.
   */
  private final TimeChooser timeChooser = new TimeChooser();



  /**
   * constructor.
   */
  public DateTimeChooser()
  {
    HorizontalPanel mainPanel = new HorizontalPanel();

    mainPanel.add(dateChooser);
    mainPanel.add(timeChooser);
    setValue(new Date());
    dateChooser.addChangeListener(changeListeners);
    timeChooser.addChangeListener(changeListeners);
    mainPanel.addStyleName(CssNames.DATE_TIME_CHOOSER_CSS_STYLE);
    initWidget(mainPanel);
  }



  /**
   * register a new {@link ChangeListener}.
   * 
   * @param listener
   *          the {@link ChangeListener} to register
   */
  public void addChangeListener(ChangeListener listener)
  {
    changeListeners.add(listener);
  }



  /**
   * returns the current value of the widget.
   * 
   * @return the current value of the widget
   */
  public Date getValue()
  {
    long time = 0;
    time += (dateChooser.getValue().getTime() / MS_BY_DAY) * MS_BY_DAY;
    time += this.timeChooser.getValue().getTime() % MS_BY_DAY;
    Date gmtDate = new Date(time);
    // Using getTimezoneOffset() to return GMT date.
    return new Date(gmtDate.getTime() + 1000l * 60 * gmtDate.getTimezoneOffset());
  }



  /**
   * getter for the enableState property.
   * 
   * @return the enableState
   */
  public boolean isEnabled()
  {
    return timeChooser.isEnabled();
  }



  /**
   * remove a registered {@link ChangeListener}.
   * 
   * @param listener
   *          the {@link ChangeListener} to remove
   * @see com.google.gwt.user.client.ui.SourcesChangeEvents#removeChangeListener(com.google.gwt.user.client.ui.ChangeListener)
   */
  public void removeChangeListener(ChangeListener listener)
  {
    changeListeners.remove(listener);
  }



  /**
   * setter for the dateFormat property.
   * 
   * @param dateFormat
   *          the dateFormat to set
   */
  public void setDateFormat(String dateFormat)
  {
    this.dateChooser.setDateFormat(dateFormat);
  }



  /**
   * setter for the enableState property.
   * 
   * @param enableState
   *          the enableState to set
   */
  public void setEnabled(boolean enableState)
  {
    timeChooser.setEnabled(enableState);
    dateChooser.setEnabled(enableState);
  }



  /**
   * set the current value of the widget.
   * 
   * @param date
   *          the current value of the widget
   */
  public void setValue(final Date date)
  {
    // Using getTimezoneOffset() to convert from GMT date to the user local
    // date.
    Date localDate = new Date(date.getTime() - 1000l * 60 * date.getTimezoneOffset());
    this.dateChooser.setValue(localDate);
    this.timeChooser.setValue(localDate);
  }

}
